package com.xsy.android.compose.wandroid.logic.network

import com.xsy.android.compose.wandroid.logic.utils.DataStoreUtils
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
 *@author: xiaosy
 *时间: 2024/7/4
 *@Description: java类作用描述
 *@Version: 1.0
 **/
object ServiceCreator {
    private const val BASE_URL = "https://www.wanandroid.com/"
    private const val CONNECT_TIMEOUT = 30L
    private const val READ_TIMEOUT = 10L
    private const val SAVE_USER_LOGIN_KEY = "user/login"
    private const val SAVE_USER_REGISTER_KEY = "user/register"
    private const val SET_COOKIE_KEY = "set-cookie"
    private const val COOKIE_NAME = "Cookie"

    private fun create(): Retrofit {
        val okHttpClientBuilder = OkHttpClient().newBuilder().apply {
            connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            //log
            val logInterceptor = HttpLoggingInterceptor()
            logInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC)
            addInterceptor(logInterceptor)
//                .addInterceptor(LoggingInterceptor.Builder()
//                    .logLevel(LogLevel.FULL)
//                    .request("Request")
//                    .response("Response")
//                    .loggable(true)
//                    .build())
            //get response cookie
            addInterceptor {
                val request = it.request()
                val response = it.proceed(request)
                val requestUrl = request.url.toString()
                val domain = request.url.host
                if ((requestUrl.contains(SAVE_USER_LOGIN_KEY) || requestUrl.contains(
                        SAVE_USER_REGISTER_KEY
                    )) && response.headers(SET_COOKIE_KEY).isNotEmpty()
                ) {
                    val cookies = response.headers(SET_COOKIE_KEY)
                    val cookie = encodeCookie(cookies)
                    saveCookie(requestUrl, domain, cookie)
                }
                response
            }

            addInterceptor {
                val request = it.request()
                val builder = request.newBuilder()
                val domain = request.url.host
                if(domain.isNotEmpty()){
                    val spDomain: String = DataStoreUtils.readStringData(domain, "")
                    if(spDomain.isNotEmpty()){
                        builder.addHeader(COOKIE_NAME, spDomain)
                    }
                }
                it.proceed(builder.build())
            }

        }

        return Retrofit.Builder().apply {
            baseUrl(BASE_URL)
                .client(okHttpClientBuilder.build())
                .addConverterFactory(GsonConverterFactory.create())
        }.build()
    }

    fun<T> create(service: Class<T>): T = create().create(service)

    private fun saveCookie(url: String?, domain: String?, cookie: String?) {
        url ?: return
        DataStoreUtils.putSyncData(url, cookie)
        domain ?: return
        DataStoreUtils.putSyncData(domain, cookie)
    }


    private fun encodeCookie(cookies: List<String>): String {
        val sb = StringBuilder()
        val set = HashSet<String>()
        cookies.map { cookie ->
            cookie.split(";".toRegex()).dropLastWhile {
                it.isEmpty()
            }.toTypedArray()
        }.forEach { it ->
            it.filterNot{set.contains(it)}.forEach{
                set.add(it)
            }
        }
        val it = set.iterator()
        while(it.hasNext()){
            val cookie = it.next()
            sb.append(cookie).append(";")
        }
        val last = sb.lastIndexOf(";")
        if(sb.length -1 == last){
            sb.deleteCharAt(last)
        }
        return sb.toString()
    }
}